/**	
*	Drawing an infinite open book : 
	infini par les deux bouts
*/

import ij.ImagePlus;
import ij.plugin.PlugIn;
import ij.process.ColorProcessor;
import ij.process.ImageProcessor;

import java.awt.Color;
import java.awt.Polygon;
import java.io.PrintStream;
import java.util.Random;

public class LivreInfini4_ extends ImagePlus implements PlugIn {
	private PrintStream output;
	private Random gene=new Random();
	

	public void run(String arg) {
		ImageProcessor primeIP = new ColorProcessor(2000, 2000);
		int R=850; 
		int r=20; 
		int xb=700,xa=1200,yb=1500,ya=1000; 
		int abscisses[]={xa,xb,xb,xa}; 
		int ordonnees[]={ya,yb,yb-R,ya-R};
		Polygon pl;
		float cstPasColor=0.1f; 
		double cstAlpha=Math.PI/1000;
		double pasColor;
		
		
		float red=0f; 
		float green=0f;
		float blue=0f;
		
		
		Polygon background=new Polygon(new int[]{0,0,2000,2000},new int[]{0,2000,2000,0},4);
		primeIP.setColor(Color.MAGENTA);
		//primeIP.setColor(new Color(red,green,blue)); 
		primeIP.fillPolygon(background);
		
		primeIP.setLineWidth(5);
		
		
		try{
			output=new PrintStream("F:/Povray/pages.txt");
			}
			catch(Exception e){System.out.println("Probleme 1 "+e); System.exit(0);}
		
		
		// Quelques constantes
		double pasAlpha;
		
		
		double limite=Math.atan(-(xa-xb+0.0)/(ya-yb+0.0));
		/* Illusion de perspective : concerne uniquement l'angle de la 
		 * partie basse du livre
		 */
		double theta=Math.PI/8;
		/* Controler l'aspect ouvert du livre */
		double ouverture=Math.PI/7;
		/* controle de la perspective */
		double coefP=0.72; 
		// Pages de gauche
		double alpha=-Math.PI/2+theta+ouverture;
		// Largeur de la couverture depassant 
		int epsilon=15; 
		
		// Deuxieme de couverture
		abscisses[0]=(int)(xa+r*Math.sin(alpha)); 
		abscisses[1]=(int)(xb+(r+epsilon)*Math.sin(alpha)); 
		abscisses[2]=(int)(xb+(R+r+2*epsilon)*Math.sin(alpha)); 
		abscisses[3]=(int)(xa+(R+r+epsilon)*Math.sin(alpha)*coefP); 
		ordonnees[0]=(int)(ya-r*Math.cos(alpha)); 
		ordonnees[1]=(int)(yb-(r-epsilon)*Math.cos(alpha)); 
		ordonnees[2]=(int)(yb-(R+r+0.8*epsilon)*Math.cos(alpha)); 
		ordonnees[3]=(int)(ya-(R+r+epsilon)*Math.cos(alpha)*coefP);
		
		pl=new Polygon(abscisses,ordonnees,4);
		
		primeIP.setColor(Color.GREEN); 
		primeIP.fillPolygon(pl);
		
		red=1f;
		green=1f;
		blue=1f;
		int index0=1;
		pasAlpha=0.0415;
		pasColor=0.01;
		while((alpha<limite)&&(index0<1000)){
		abscisses[0]=(int)(xa+r*Math.sin(alpha)); 
		abscisses[1]=(int)(xb+r*Math.sin(alpha)); 
		abscisses[2]=(int)(xb+(R+r)*Math.sin(alpha)); 
		abscisses[3]=(int)(xa+(R+r)*Math.sin(alpha)*coefP); 
		ordonnees[0]=(int)(ya-r*Math.cos(alpha)); 
		ordonnees[1]=(int)(yb-r*Math.cos(alpha)); 
		ordonnees[2]=(int)(yb-(R+r)*Math.cos(alpha)); 
		ordonnees[3]=(int)(ya-(R+r)*Math.cos(alpha)*coefP);
		
		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.DARK_GRAY); 
		primeIP.drawPolygon(pl); 
		primeIP.setColor(new Color(red,green,blue)); 
		int ind=1+gene.nextInt(9); 
		output.println("object{pageR"+ind+"  rotate "+alpha/Math.PI*180+"*x}"); 
		primeIP.fillPolygon(pl);
		pasAlpha=pasAlpha*1.05;
		/*
		pasColor=pasColor*1.1; 
		if(red+pasColor<0.999){
		red+=pasColor; 
		green+=pasColor;
		blue+=pasColor;
			
		}
		*/
		alpha=alpha+pasAlpha;
		index0++;
		
		}
		
		// Pages de droite
		
		
		alpha=Math.PI/2+theta; 
		
		// Troisieme de couverture
		abscisses[0]=(int)(xa+r*Math.sin(alpha)); 
		abscisses[1]=(int)(xb+(r-epsilon)*Math.sin(alpha)); 
		abscisses[2]=(int)(xb+(R+r+2*epsilon)*Math.sin(alpha)); 
		abscisses[3]=(int)(xa+(R+r+epsilon)*Math.sin(alpha)*coefP); 
		ordonnees[0]=(int)(ya-r*Math.cos(alpha)); 
		ordonnees[1]=(int)(yb-(r+epsilon)*Math.cos(alpha)); 
		ordonnees[2]=(int)(yb-(R+r+4*epsilon)*Math.cos(alpha)); 
		ordonnees[3]=(int)(ya-(R+r+epsilon)*Math.cos(alpha)*coefP);
		
		pl=new Polygon(abscisses,ordonnees,4);
	
		primeIP.setColor(Color.GREEN); 
		
		primeIP.fillPolygon(pl);
		
		
		red=0f;
		green=0f;
		blue=0f;
		index0=1;
		pasAlpha=cstAlpha;
		pasColor=0.01;
		
		
		while((alpha>limite)&&(index0<1000)){
		abscisses[0]=(int)(xa+r*Math.sin(alpha)); 
		abscisses[1]=(int)(xb+r*Math.sin(alpha)); 
		abscisses[2]=(int)(xb+(R+r)*Math.sin(alpha)); 
		abscisses[3]=(int)(xa+(R+r)*Math.sin(alpha)*coefP); 
		ordonnees[0]=(int)(ya-r*Math.cos(alpha)); 
		ordonnees[1]=(int)(yb-r*Math.cos(alpha)); 
		ordonnees[2]=(int)(yb-(R+r)*Math.cos(alpha)); 
		ordonnees[3]=(int)(ya-(R+r)*Math.cos(alpha)*coefP);
		
		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.DARK_GRAY); 
		primeIP.drawPolygon(pl); 
		primeIP.setColor(new Color(red,green,blue)); 
		int  ind=1+gene.nextInt(9); 
		output.println("object{pageR"+ind+"  rotate "+alpha/Math.PI*180+"*x}"); 
		primeIP.fillPolygon(pl);
	
		//pasAlpha=pasAlpha*1.025;
		pasAlpha=pasAlpha*Math.pow(index0+0.0,0.008);
		pasColor=pasColor*Math.pow(1.18,(index0/5.0)); 
		if(red+pasColor<0.999){
		red+=pasColor; 
		green+=pasColor;
		blue+=pasColor;	
		}
		alpha=alpha-pasAlpha;
		index0++;
		}
		System.out.println(pasAlpha);
		// Tranche avant gauche
		alpha=-Math.PI/2+theta+ouverture;
		
		abscisses[0]=(int)(xb+(r+epsilon)*Math.sin(alpha)); 
		abscisses[1]=(int)(xb+(R+r+2*epsilon)*Math.sin(alpha)); 
		abscisses[2]=abscisses[1]-15;
		abscisses[3]=abscisses[0]-15;	 
		ordonnees[0]=(int)(yb-(r-epsilon)*Math.cos(alpha)); 
		ordonnees[1]=(int)(yb-(R+r+0.8*epsilon)*Math.cos(alpha)); 
		ordonnees[2]=ordonnees[1]+15;
		ordonnees[3]=ordonnees[0]+15;
		
		pl=new Polygon(abscisses,ordonnees,4);
		primeIP.setColor(Color.BLUE); 
		primeIP.fillPolygon(pl);
		
		// Tranche avant droite	
		
		alpha=Math.PI/2+theta; 
		 
		abscisses[0]=(int)(xb+(r-epsilon)*Math.sin(alpha)); 
		abscisses[1]=(int)(xb+(R+r+2*epsilon)*Math.sin(alpha)); 
		abscisses[2]=abscisses[1]-8;
		abscisses[3]=abscisses[0]-8;
 
		ordonnees[0]=(int)(yb-(r+epsilon)*Math.cos(alpha)); 
		ordonnees[1]=(int)(yb-(R+r+4*epsilon)*Math.cos(alpha)); 
		ordonnees[2]=ordonnees[1]+15;
		ordonnees[3]=ordonnees[0]+15;
		
		pl=new Polygon(abscisses,ordonnees,4);
		
		primeIP.setColor(Color.BLUE); 
		primeIP.fillPolygon(pl);
		setProcessor("Verifying", primeIP);
		show();
	}

	

}
